﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;

namespace LynxWebLog
{

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class MaliciousActivityChecksFilterAttribute : AuthorizeAttribute
    {
        //private readonly IAuthentication _authentication;

        public MaliciousActivityChecksFilterAttribute()
        {
            //_authentication = authentication;
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            try {
                IPAddress _ipAddress = IPAddress.Parse(filterContext.Controller.ControllerContext.RequestContext.HttpContext.Request.UserHostAddress);
                IPrincipal user = filterContext.Controller.ControllerContext.HttpContext.User;

                if (user.IsInRole("BlogAdmin")) {
                    return;
                }

                List<IPAddress> _overrideIP = new List<IPAddress>();
                if (HttpContext.Current.Application["__BlogGovernorOverrideIP"] != null) {
                    _overrideIP = (List<IPAddress>)HttpContext.Current.Application["__BlogGovernorOverrideIP"];
                }
                if (_overrideIP.Contains(_ipAddress)) {
                    return;
                }
                List<IPAddressRange> _overrideIPRange = new List<IPAddressRange>();
                if (HttpContext.Current.Application["__BlogGovernorOverrideIPRange"] != null) {
                    _overrideIPRange = (List<IPAddressRange>)HttpContext.Current.Application["__BlogGovernorOverrideIPRange"];
                }
                if (_overrideIPRange != null) {
                    foreach (IPAddressRange range in _overrideIPRange) {
                        if (range.IsInRange(_ipAddress)) {
                            return;
                        }
                    }
                }

                List<IPAddress> _blacklistIP = new List<IPAddress>();
                if (HttpContext.Current.Application["__BlogBlacklistIP"] != null) {
                    _blacklistIP = (List<IPAddress>)HttpContext.Current.Application["__BlogBlacklistIP"];
                }
                if (_blacklistIP.Contains(_ipAddress)) {
                    throw new UnauthorizedAccessException();
                }

                List<IPAddressRange> _blacklistIPRange = new List<IPAddressRange>();
                if (HttpContext.Current.Application["__BlogGovernorOverrideIPRange"] != null) {
                    _blacklistIPRange = (List<IPAddressRange>)HttpContext.Current.Application["__BlogGovernorOverrideIPRange"];
                }
                if (_blacklistIPRange != null) {
                    foreach (IPAddressRange range in _blacklistIPRange) {
                        if (range.IsInRange(_ipAddress)) {
                            throw new UnauthorizedAccessException();
                        }
                    }
                }

                Dictionary<IPAddress, DateTime> wikiWriteGovernor = new Dictionary<IPAddress, DateTime>();
                if (HttpContext.Current.Application["__BlogWriteGovernor"] != null) {
                    wikiWriteGovernor = (Dictionary<IPAddress, DateTime>)HttpContext.Current.Application["__BlogWriteGovernor"];
                    if (wikiWriteGovernor.ContainsKey(_ipAddress)) {
                        DateTime lastWriteAttempt = wikiWriteGovernor[_ipAddress];
                        wikiWriteGovernor[_ipAddress] = DateTime.Now;
                        int freq = (int)HttpContext.Current.Application["__GovernorWriteFreq"];
                        if (DateTime.Now.Ticks - lastWriteAttempt.Ticks < freq * TimeSpan.TicksPerSecond) {
                            HttpContext.Current.Application.Remove("__BlogWriteGovernor");
                            HttpContext.Current.Application.Add("__BlogWriteGovernor", wikiWriteGovernor);
                            throw new UnauthorizedAccessException();
                        }
                        HttpContext.Current.Application.Remove("__BlogWriteGovernor");
                        HttpContext.Current.Application.Add("__BlogWriteGovernor", wikiWriteGovernor);
                    } else {
                        wikiWriteGovernor.Add(_ipAddress, DateTime.Now);
                        HttpContext.Current.Application.Remove("__BlogWriteGovernor");
                        HttpContext.Current.Application.Add("__BlogWriteGovernor", wikiWriteGovernor);
                    }
                } else {
                    wikiWriteGovernor.Add(_ipAddress, DateTime.Now);
                    HttpContext.Current.Application.Add("__BlogWriteGovernor", wikiWriteGovernor);
                }

            }
            catch (Exception ex) {
                throw new UnauthorizedAccessException();
            }

        }
    }
}